/**
 * 格式化工具函数
 * @author Wu.Liang
 * @date 2025-01-21
 */

import dayjs from 'dayjs'

/**
 * 日期格式化
 * @param {string|Date} date 日期
 * @param {string} format 格式
 * @returns {string}
 */
export const formatDate = (date, format = 'YYYY-MM-DD') => {
  if (!date) return ''
  return dayjs(date).format(format)
}

/**
 * 时间格式化
 * @param {string|Date} date 日期
 * @param {string} format 格式
 * @returns {string}
 */
export const formatTime = (date, format = 'YYYY-MM-DD HH:mm:ss') => {
  if (!date) return ''
  return dayjs(date).format(format)
}

/**
 * 日期时间格式化
 * @param {string|Date} date 日期
 * @param {string} format 格式
 * @returns {string}
 */
export const formatDateTime = (date, format = 'YYYY-MM-DD HH:mm:ss') => {
  if (!date) return ''
  return dayjs(date).format(format)
}

/**
 * 金额格式化
 * @param {number} amount 金额
 * @param {number} decimals 小数位数
 * @returns {string}
 */
export const formatAmount = (amount, decimals = 2) => {
  if (amount === null || amount === undefined) return '0.00'
  
  const num = parseFloat(amount)
  if (isNaN(num)) return '0.00'
  
  return num.toFixed(decimals)
}

/**
 * 相对时间格式化
 * @param {string|Date} date 日期
 * @returns {string}
 */
export const formatRelativeTime = (date) => {
  if (!date) return ''
  
  const now = dayjs()
  const target = dayjs(date)
  const diff = now.diff(target, 'minute')
  
  if (diff < 1) return '刚刚'
  if (diff < 60) return `${diff}分钟前`
  
  const hourDiff = now.diff(target, 'hour')
  if (hourDiff < 24) return `${hourDiff}小时前`
  
  const dayDiff = now.diff(target, 'day')
  if (dayDiff < 30) return `${dayDiff}天前`
  
  const monthDiff = now.diff(target, 'month')
  if (monthDiff < 12) return `${monthDiff}个月前`
  
  const yearDiff = now.diff(target, 'year')
  return `${yearDiff}年前`
}

/**
 * 金额格式化
 * @param {number} amount 金额
 * @param {number} decimals 小数位数
 * @param {string} currency 货币符号
 * @returns {string}
 */
export const formatMoney = (amount, decimals = 2, currency = '¥') => {
  if (amount === null || amount === undefined) return ''
  
  const num = parseFloat(amount)
  if (isNaN(num)) return ''
  
  return `${currency}${num.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`
}

/**
 * 手机号格式化
 * @param {string} phone 手机号
 * @returns {string}
 */
export const formatPhone = (phone) => {
  if (!phone) return ''
  
  const phoneStr = String(phone).replace(/\D/g, '')
  if (phoneStr.length !== 11) return phone
  
  return phoneStr.replace(/(\d{3})(\d{4})(\d{4})/, '$1****$3')
}

/**
 * 手机号脱敏
 * @param {string} phone 手机号
 * @returns {string}
 */
export const maskPhone = (phone) => {
  if (!phone) return ''
  
  const phoneStr = String(phone).replace(/\D/g, '')
  if (phoneStr.length !== 11) return phone
  
  return phoneStr.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}

/**
 * 身份证号格式化
 * @param {string} idCard 身份证号
 * @returns {string}
 */
export const formatIdCard = (idCard) => {
  if (!idCard) return ''
  
  const idCardStr = String(idCard).replace(/\D/g, '')
  if (idCardStr.length !== 18) return idCard
  
  return idCardStr.replace(/(\d{6})\d{8}(\d{4})/, '$1********$2')
}

/**
 * 身份证号脱敏
 * @param {string} idCard 身份证号
 * @returns {string}
 */
export const maskIdCard = (idCard) => {
  if (!idCard) return ''
  
  const idCardStr = String(idCard).replace(/\D/g, '')
  if (idCardStr.length !== 18) return idCard
  
  return idCardStr.replace(/(\d{6})\d{8}(\d{4})/, '$1********$2')
}

/**
 * 银行卡号格式化
 * @param {string} cardNumber 银行卡号
 * @returns {string}
 */
export const formatBankCard = (cardNumber) => {
  if (!cardNumber) return ''
  
  const cardStr = String(cardNumber).replace(/\D/g, '')
  if (cardStr.length < 16) return cardNumber
  
  return cardStr.replace(/(\d{4})(?=\d)/g, '$1 ')
}

/**
 * 银行卡号脱敏
 * @param {string} cardNumber 银行卡号
 * @returns {string}
 */
export const maskBankCard = (cardNumber) => {
  if (!cardNumber) return ''
  
  const cardStr = String(cardNumber).replace(/\D/g, '')
  if (cardStr.length < 16) return cardNumber
  
  return cardStr.replace(/(\d{4})\d{8}(\d{4})/, '$1********$2')
}

/**
 * 文件大小格式化
 * @param {number} bytes 字节数
 * @returns {string}
 */
export const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 B'
  
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

/**
 * 数字格式化
 * @param {number} num 数字
 * @param {number} decimals 小数位数
 * @returns {string}
 */
export const formatNumber = (num, decimals = 0) => {
  if (num === null || num === undefined) return ''
  
  const number = parseFloat(num)
  if (isNaN(number)) return ''
  
  return number.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

/**
 * 百分比格式化
 * @param {number} num 数字
 * @param {number} decimals 小数位数
 * @returns {string}
 */
export const formatPercent = (num, decimals = 2) => {
  if (num === null || num === undefined) return ''
  
  const number = parseFloat(num)
  if (isNaN(number)) return ''
  
  return `${(number * 100).toFixed(decimals)}%`
}

/**
 * 地址格式化
 * @param {object} address 地址对象
 * @returns {string}
 */
export const formatAddress = (address) => {
  if (!address) return ''
  
  const parts = []
  if (address.province) parts.push(address.province)
  if (address.city) parts.push(address.city)
  if (address.district) parts.push(address.district)
  if (address.street) parts.push(address.street)
  if (address.detail) parts.push(address.detail)
  
  return parts.join(' ')
}

/**
 * 状态格式化
 * @param {string|number} status 状态值
 * @param {object} statusMap 状态映射
 * @returns {string}
 */
export const formatStatus = (status, statusMap) => {
  if (!statusMap || typeof statusMap !== 'object') return String(status)
  
  return statusMap[status] || String(status)
}

/**
 * 性别格式化
 * @param {string|number} gender 性别
 * @returns {string}
 */
export const formatGender = (gender) => {
  const genderMap = {
    0: '未知',
    1: '男',
    2: '女',
    '0': '未知',
    '1': '男',
    '2': '女',
    'male': '男',
    'female': '女',
    'unknown': '未知'
  }
  
  return genderMap[gender] || '未知'
}

/**
 * 布尔值格式化
 * @param {boolean|string|number} value 值
 * @param {string} trueText 真值文本
 * @param {string} falseText 假值文本
 * @returns {string}
 */
export const formatBoolean = (value, trueText = '是', falseText = '否') => {
  if (value === true || value === 1 || value === '1' || value === 'true') {
    return trueText
  }
  return falseText
} 